﻿using HAF.LogUtility;
using Newtonsoft.Json.Linq;
using RDS.Core;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Reflection;

namespace RDSEngine.WorkItems
{
    public class LoadWorker
    {
        private string _className = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name;

        private LoadWorker() {}

        private static LoadWorker _loader;
        public static LoadWorker GetInstance()
        {
            return _loader ?? (_loader = new LoadWorker());
        }

        private readonly string plugDir = "Plugins";
        Assembly assembly = null;

        /// <summary>
        /// 加载第三方动态库/插件
        /// </summary>
        /// <param name="fileName"></param>
        public void LoadAssembly(string fileName)
        {
            if (string.IsNullOrEmpty(fileName))
            {
                LogHelper.WriteErrorLog("金沙引擎：加载工作项失败，工作项动态库文件为空！");
                return;
            }
            string fullPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, plugDir, fileName);
            if (File.Exists(fullPath))
            {
                //加载程序集(dll文件地址)，使用Assembly类   
                //assembly = Assembly.LoadFile(fullPath);
                assembly = Assembly.LoadFrom(fullPath);
                //注意LoadFile和LoadFrom的区别
            }
            else
            {
                LogHelper.WriteErrorLog("金沙引擎：加载工作项失败，未找到工作项动态库文件！");
            }
        }

        /// <summary>
        /// 调用程序集中类及方法
        /// </summary>
        /// <param name="fullClassName"></param>
        /// <param name="methodName"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public bool Invoke(string fullClassName, string methodName, params Object[] args)
        {
            try
            {
                if (assembly == null)
                {
                    LogHelper.WriteErrorLog("金沙引擎：插件对象不存在！");
                    return false;
                }

                //获取类型，参数（名称空间+类名）
                Type tp = assembly.GetType(fullClassName);
                if (tp == null)
                {
                    LogHelper.WriteErrorLog("金沙引擎：插件指定调用的类不存在！");
                    return false;
                }

                //获取当前对象全部方法
                //MethodInfo[] methodlst = tp.GetMethods();
                //foreach (var item in methodlst)
                //{
                //    Console.WriteLine(item.Name);
                //}

                //通过方法名称获取方法
                MethodInfo method = tp.GetMethod(methodName);
                if (method != null)
                {
                    //ParameterInfo[] parameters = method.GetParameters();
                    //for (int i = 0; i < parameters.Length; i++)
                    //{
                    //    LogHelper.WriteDebugLog("Paramter.Name {0} Paramter.Type {1}", parameters[i].Name, parameters[i].ParameterType);
                    //    Console.WriteLine($"Parameter Name: {parameters[i].Name}, Parameter Type: {parameters[i].ParameterType}");
                    //    //Type typ = args[i].GetType();
                    //    parameters[i].GetType().IsClass()
                    //    if (args[i].GetType() != parameters[i].ParameterType)
                    //    {
                    //        if (args[i] is JArray)
                    //        {
                    //            var tmpTasks = (args[1] as JArray).ToObject < parameters[i].DefaultValue > ();
                    //        }
                    //        //对象必须实现 IConvertible。
                    //        args[i] = Convert.ChangeType(args[i], parameters[i].ParameterType);
                    //        TypeConverter converter = TypeDescriptor.GetConverter(parameters[i].ParameterType);
                    //        //var a = new List<Object>(args[i]);
                    //        //var a = Converter.GenericListTypeConverter< parameters[i].ParameterType > ().ConvertFrom(args[i]);
                    //        //args[i] = (parameters[i].ParameterType)args[i];
                    //    }
                    //}
                    //foreach (var item in parameters)
                    //{
                    //    LogHelper.WriteDebugLog("Paramter.Name {0} Paramter.Type {1}", item.Name, item.ParameterType);
                    //    Console.WriteLine($"Parameter Name: {item.Name}, Parameter Type: {item.ParameterType}");
                    //}
                    //生成插件类实例对象
                    Object obj = Activator.CreateInstance(tp);
                    //调用类方法
                    method.Invoke(obj, args);
                }
                else
                {
                    LogHelper.WriteErrorLog("金沙引擎：插件调用的方法不存在！");
                    return false;
                }

                return true;
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrorLog(string.Format("金沙引擎：方法{0}发生异常：{1}", System.Reflection.MethodBase.GetCurrentMethod().Name, ex.ToString()));
                return false;
            }
            
        }

        /// <summary>
        /// 获取当前任务集合
        /// </summary>
        /// <returns></returns>
        public List<RunTask> ListWorker()
        {
            try
            {
                //超时任务处理
                List<RunTask> extTasks = RuntimeAdapter.Tasks.FindAll(t => t.CreateTime < DateTime.Now.AddHours(-6) && t.State < 5);
                foreach (var item in extTasks)
                {
                    item.State = 9;
                    item.EndTime = DateTime.Now;
                }

                //更新所有任务状态
                //foreach (var item in RuntimeAdapter.Tasks)
                //{
                //    if (Dispatcher.GetInstance().RunWorkItems.Exists(t => t.TaskID == item.ID))
                //    {
                //        var task = Dispatcher.GetInstance().RunWorkItems.Find(t => t.TaskID == item.ID);
                //        item.State = (int)task.Statu;
                //    }
                //    else
                //    {
                //        if (item.State == 2)
                //        {
                //            item.State = 5;
                //            item.EndTime = DateTime.Now;
                //        }
                //    }
                //}

                //自动删除一天前的数据（可能会冲突：删除的时候正好添加新的任务）
                if (RuntimeAdapter.Tasks.Exists(t=> t.CreateTime < DateTime.Now.AddDays(-1)))
                {
                    //LogHelper.WriteDebugLogEx("有超过一天的数据将被自动删除");
                    RuntimeAdapter.Tasks.RemoveAll(t => t.CreateTime < DateTime.Now.AddDays(-1));
                }

                return RuntimeAdapter.Tasks;

            }
            catch (Exception ex)
            {
                LogHelper.WriteErrorLog(string.Format("方法{0}发生异常：{1}", System.Reflection.MethodBase.GetCurrentMethod().Name, ex.ToString()));
                return null;
            }

        }
    }
}
